iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
AI/ ML & Data

使用 jq 處理資料系列 第 29

Day29: 應用錯誤處理

  • 分享至 

  • xImage
  •  

昨天我們認識了 jq 錯誤處理,有拋錯的error()、捕捉錯誤但不處理的try欄位?,以及可以自訂處理錯誤的 try-catch。 今天我們來修改之前寫的 data_processing.jq ,加入基本的錯誤處理吧。

修改 process_input,檢查輸入類型

我們在 data_processing.jq 裡面有定義 process_input:

# 處理透過 slurp 讀進來的陣列,回傳物件
def process_input:
  {
    direction: .[0], # 來自 direction.json
    typhoon: .[1],   # 來自 typhoon1005.json
    beaufort: .[2]   # 來自 beaufort_wind.json
  };

這個函式雖然沒有參數,但它有從來源期望接收的輸入是"長度為3的陣列",因此我們可以針對輸入做檢查,加上 if-else-then-end 做判斷,如果不符合就拋錯,如下:

# 處理透過 slurp 讀進來的陣列,回傳物件
def process_input:
  debug(type, keys) | # 暫時顯示用
  if (type=="array" and length==3) then 
    {
      direction: .[0], # 來自 direction.json
      typhoon: .[1],   # 來自 typhoon1005.json
      beaufort: .[2]   # 來自 beaufort_wind.json
    }
  else
    error("Expected array length of 3, but got \(type) " + (length | tostring))  
  end;

如此一來,當有人使用 process_input 這個函式,卻沒有給予正確的輸入,就會拋出錯誤訊息。參考下圖,這是我手動刪除最後一個輸入 beaufort_wind.json 的結果:

https://ithelp.ithome.com.tw/upload/images/20241013/200783893VHxUu6mIO.png

修改 content,加入參數

我們在 data_processing.jq 原本定義 content 函式是沒有帶參數的。如果加入將颱風名稱作為參數,下次有新的颱風警報時,就可以直接改參數。所以增加參數s修改如下:

# 主要的資料內容,回傳颱風路徑陣列
def content(s):
  .beaufort as $wind | 
  .direction as $direction |
  .typhoon.records.tropicalCyclones.tropicalCyclone[] | 
  select(.typhoonName==s) | 
  .analysisData.fix[-5:][] |
  (下略)

如果只修改到這邊,執行 krathon2024_json.bat 程式,會看到以下錯誤訊息:

jq: error: content/0 is not defined at <top-level>, line 4:
include "data_processing"; process_input | header, [ content ][] | @tsv        

jq: 1 compile error

對於 "有 1 個參數的content函式" ,通常會寫成 content/1;往後類推 "有 2 個參數的content函式"會是 content/2。那麼 content/0 呢? 答對了,就是 "沒有參數的content函式"。 😝

所以上面的錯誤訊息就是告訴我們,它找不到"沒有參數的content函式"。這是因為我們剛才將 content/0 修改成 content/1 的關係。因此我們可以再加入一個 content/0 ,並在函式中輸入 "KRATHON" 作為預設的颱風名稱,就能解決這個錯誤訊息了。如下:

def content:
  content("KRATHON");

山陀兒颱風還沒登陸前,我下載的 typhoon0930.json 裡面有燕子(JEBI)的路徑資料,為了方便觀察是不是輸入"JEBI" 就能看到燕子颱風的資料,我增加了 jebi2024_json.batmain_jebi.jq,可以執行 jebi2024_json.bat 來看到燕子(JEBI)的顯示結果。

修改 content ,檢查輸入類型

content/1 有了輸入參數,期望接收的輸入參數是字串類型。修改程式如下:

# 主要的資料內容,回傳颱風路徑陣列
def content(s):
  if ((s|type)=="string") then 
    (略)
  else
    error("Expected type string, but got  " + (s | type))  
  end;    

def content:
  content(1); # 暫時改為數字

因為要看這個錯誤處理修改之後是否有辦法揪出不是字串的輸入參數錯誤,我們暫時把 content/0 修改為傳入數字 1,於是看到以下錯誤訊息:

jq: error (at beaufort_wind.json:96): Expected type string, but got  number

為了方便重現這個錯誤,我在程式碼裡面增加了 error2024_json.batmain_error.jq。可以執行 error2024_json.bat 來看到參數錯誤的訊息。

結論

今天我們運用了昨天學到的 error() ,幫現有的 process_inputcontent 函式加上基本的輸入參數類型檢查,並且增加 content/1 讓之後查詢新的颱風名稱更方便。今天修改的部分可以參考 程式碼

感謝自己,持續努力的學習。 😊


上一篇
Day28: jq 的錯誤處理
下一篇
Day30: jq alternative operator 學無止境
系列文
使用 jq 處理資料30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言